#include "datafilequi.h"


DataFileQui::DataFileQui()
{
    clear();
}

void DataFileQui::convertDataToEmbAbs(s16 flag)
{
    m_absData.clear();
    getQuiMinMax();

    QuiFileHead head;

    // 图形数据
    int i, datasize, idx;
    BYTE ch1, ch2;
    WORD tmpls,lsdata;
    double deltx1, delty1, deltx2, delty2;
    double threex[4], threey[4];
    s16 nmstep;

    double factorx, factory, unitmuti;
    memcpy(&head, m_quiFileData.data(), sizeof(QuiFileHead));
    unitmuti = getMutiUnit(head.unit);

    double left = head.left * unitmuti;     // 左边
    double front = head.front * unitmuti;   // 前边
    double scanx = head.scanX * unitmuti;   // 宽度
    double scany = head.scanY * unitmuti;   // 长度

    if (scanx < 1)
    {
        scanx = 1;
    }
    if (scany < 1)
    {
        scany = 1;
    }

    // 计算缩放系数
    factorx = (double)((m_maxX-m_minX) / (scanx));
    factory = (double)((m_maxY-m_minY) / (scany));

    if(factorx == 0){factorx = 1;}
    if(factory == 0){factory = 1;}
    //        factorx = 1;
    //        factory = 1;

    if(flag != 1)
    {
        factorx = 1;
        factory = 1;
    }

    nmstep = head.normalStep * unitmuti;
    if(nmstep == 0)
    {
        nmstep = 200;    //单位0.01mm（2mm）
    }

    i = sizeof(QuiFileHead);
    datasize = m_quiFileData.size();

    DsAbsItem absItem;
    memset(&absItem,0,sizeof(DsAbsItem));

    //将第一个点加进来
    absItem.ctrl = m_firstPoint.ctrl;
    absItem.ax = m_firstPoint.x / factorx;
    absItem.ay = m_firstPoint.y / factory;
    m_absData.append((char*)&absItem,sizeof(DsAbsItem));

    // 根据QUI图元生成abs数据
    while(i < datasize)
    {
        // 图元类型
        if (i >= datasize){break;}
        ch1 = m_quiFileData.at(i++);
        if (i >= datasize){break;}
        ch2 = m_quiFileData.at(i++);
        tmpls = (unsigned short) (ch2 * 256) + ch1;

        if(tmpls == 0xffff)		// 结束
        {
            break;
        }

        switch(tmpls)
        {
        case QUI_TYPE_LINE: // 直线
        case QUI_TYPE_STEP: // 跨步
        case QUI_TYPE_HSTEP: // 翻头跨步
        {
            //增加剪线
            if(tmpls == QUI_TYPE_STEP || tmpls == QUI_TYPE_HSTEP)
            {
                if((u32)m_absData.size() >= sizeof(DsAbsItem))
                {
                    memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem));
                    absItem.ctrl = DATA_CUTTRD;
                    m_absData.append((char*)&absItem,sizeof(DsAbsItem));
                }
            }

            // 点个数
            if (i >= datasize){break;}
            ch1 = m_quiFileData.at(i++);
            if (i >= datasize){break;}
            ch2 = m_quiFileData.at(i++);
            lsdata = (unsigned short)ch2 * 256 + ch1;

            if (lsdata > 1)
            {
                // 第一个点
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                deltx2 = (ch2 * 256.0 + ch1)/factorx;

                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                delty2 = (ch2 * 256.0 + ch1)/factory;

                for(idx = 1; idx < lsdata; idx++)	// 其余的点
                {
                    deltx1 = deltx2;
                    delty1 = delty2;

                    if (i >= datasize){break;}
                    ch1 = m_quiFileData.at(i++);
                    if (i >= datasize){break;}
                    ch2 = m_quiFileData.at(i++);
                    deltx2 = (ch2 * 256.0 + ch1)/factorx;

                    if (i >= datasize){break;}
                    ch1 = m_quiFileData.at(i++);
                    if (i >= datasize){break;}
                    ch2 = m_quiFileData.at(i++);
                    delty2 = (ch2 * 256.0 + ch1)/factory;

                    // 处理直线
                    calcLine(deltx1, delty1, deltx2, delty2, nmstep, m_absData, tmpls);
                }
                if (idx != lsdata)
                {
                    break;
                }
            }
            break;
        }
        case QUI_TYPE_ARC: // 三点圆弧
        {
            for (idx = 0; idx < 3; idx++)
            {
                // 点x
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threex[idx] = (ch2 * 256.0 + ch1)/factorx;

                // 点y
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threey[idx] = (ch2 * 256.0 + ch1)/factory;
            }

            calcCurve(threex, threey, nmstep, m_absData);

            if (idx != 3)
            {
                break;
            }
            break;
        }
        case QUI_TYPE_BES: // 贝塞尔曲线
        {
            for (idx = 0; idx < 4; idx++)
            {
                // 点x
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threex[idx] = (ch2 * 256.0 + ch1)/factorx;

                // 点y
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threey[idx] = (ch2 * 256.0 + ch1)/factory;
            }

            // 处理贝塞尔曲线
            QList<QPointF> splineListXY;//拟合后的点
            splineListXY.clear();
            getBezierPointList(threex, threey, nmstep,splineListXY);

            QList<QPointF> splitListXY;//均分后的点
            splitListXY.clear();
            if(splineListXY.size() > 0)
            {
                getCurvePointFillLine(splineListXY,nmstep,splitListXY,0,OBJECT_STITCHLEN_NEW_SAMALL);
            }

            //添加贝塞尔曲线数据点
            for(int i = 0; i < splitListXY.size(); i++)
            {
                memset(&absItem,0,sizeof(DsAbsItem));

                deltx1 = splitListXY[i].x();
                delty1 = splitListXY[i].y();

                absItem.ctrl = DATA_SEWING;
                absItem.ax = deltx1;
                absItem.ay = delty1;
                m_absData.append((char*)&absItem,sizeof(DsAbsItem));
            }
            //calcBezier(threex, threey, nmstep, m_absData);

            if (idx != 4)
            {
                break;
            }
            break;
        }
        default:
            break;
        }
    }

    //生成绝对坐标数据的文件头
    creatAbsHeadAndAr(left, front);
}

// 生成abs文件头
void DataFileQui::creatAbsHeadAndAr(double left, double front)
{
    DataDs16FileHead dhead;
    memset(&dhead, 0, sizeof(DataDs16FileHead));

    int stepSize = m_absData.size()/sizeof(DsAbsItem);
    if(stepSize <= 0)
    {
        return;
    }

    DsAbsItem * absDataPtr = (DsAbsItem *)(m_absData.data());

    double minX, maxX, minY, maxY;
    minX = S32_MAX;
    maxX = S32_MIN;
    minY = S32_MAX;
    maxY = S32_MIN;

    double prex,prey,curx,cury,dx,dy,ar;
    prex = prey = curx = cury = dx = dy = ar = 0;

    // 求最大最小值
    for (int i = 0; i < stepSize; i++)
    {
        absDataPtr->ax *= QUI_DATADIRX;
        absDataPtr->ay *= QUI_DATADIRY;

        curx = absDataPtr->ax;
        cury = absDataPtr->ay;

        if(curx > maxX)
        {
            maxX = curx;
        }
        if(curx < minX)
        {
            minX = curx;
        }

        if(cury > maxY)
        {
            maxY = cury;
        }
        if(cury < minY)
        {
            minY = cury;
        }
        absDataPtr++;
    }

    // 计算 ar
    prex = absDataPtr->ax;    //起始点
    prey = absDataPtr->ay;
    absDataPtr = (DsAbsItem *)(m_absData.data());

    for (int i = 0; i < stepSize; i++)
    {
        curx = absDataPtr->ax;
        cury = absDataPtr->ay;

        dx = curx - prex;
        dy = cury - prey;

        double tar = atan2(dy,dx);
        ar = (tar*10000+0.5*(tar>0?1:-1));
        absDataPtr->ar = ar;

        prex = curx;
        prey = cury;
        absDataPtr++;
    }

    // 根据坐标方向和left,front参数，平移绝对数据，使绝对数据处于 参数设置的范围内
    double ofstx, ofsty;
    ofstx = left - minX;
    ofsty = front - minY;
    absDataPtr = (DsAbsItem *)(m_absData.data());
    for (int i = 0; i < stepSize; i++)
    {
        absDataPtr->ax += ofstx;
        absDataPtr->ay += ofsty;
        absDataPtr++;
    }
    minX += ofstx;
    minY += ofsty;
    maxX += ofstx;
    maxY += ofsty;

    m_minX = minX;
    m_maxX = maxX;
    m_minY = minY;
    m_maxY = maxY;

    // 增加结束码
    if((u32)m_absData.size() >= sizeof(DsAbsItem))
    {
        DsAbsItem absItem;
        memset(&absItem,0,sizeof(DsAbsItem));
        memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem));
        absItem.ctrl = DATA_NULL;
        m_absData.append((char*)&absItem,sizeof(DsAbsItem));
        stepSize++;
    }

    //生成文件头
    dhead.maxX = maxX;
    dhead.maxY = maxY;
    dhead.minX = minX;
    dhead.minY = minY;

    dhead.beginX = 0;
    dhead.beginY = 0;
    dhead.beginR = 0;

    dhead.anchorX = 0;
    dhead.anchorY = 0;
    dhead.itemNums = stepSize;
    dhead.dataSize = stepSize*sizeof(DsAbsItem);    // 数据字节数
    dhead.bytesPerItem = sizeof(DsAbsItem);         // 每项占的字节数
    dhead.dataChecksum = calcCheckSum32((u8 *)(m_absData.data()) , dhead.dataSize);;	// 数据累加校验和
    dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）
    dhead.fileid = dhead.checkCrc;
    m_absData.insert(0,(char*)&dhead,sizeof(DataDs16FileHead));
}

void DataFileQui::getQuiMinMax()
{
    QuiFileHead head;
    memcpy(&head, m_quiFileData.data(), sizeof(QuiFileHead));

    int i, idx, datasize;
    unsigned char ch1, ch2;
    unsigned short tmpls, lsdata;
    double deltx, delty;
    double threex[4], threey[4];

    int first = 0;
    double minx, maxx, miny, maxy;

    minx = S32_MAX;
    maxx = S32_MIN;
    miny = S32_MAX;
    maxy = S32_MIN;

    i = sizeof(QuiFileHead);
    datasize = m_quiFileData.size();
    while(i < datasize)
    {
        // 图元类型
        if (i >= datasize){break;}
        ch1 = m_quiFileData.at(i++);
        if (i >= datasize){break;}
        ch2 = m_quiFileData.at(i++);
        tmpls = (unsigned short) (ch2 * 256) + ch1;

        if(tmpls == 0xffff)		// 结束
        {
            break;
        }

        switch(tmpls)
        {
        case QUI_TYPE_LINE: // 直线(折线)
        case QUI_TYPE_STEP: // 跨步
        case QUI_TYPE_HSTEP: // 翻头跨步
        {
            // 点个数
            if (i >= datasize){break;}
            ch1 = m_quiFileData.at(i++);
            if (i >= datasize){break;}
            ch2 = m_quiFileData.at(i++);
            lsdata = (unsigned short)ch2 * 256 + ch1;

            if (lsdata > 1)
            {
                for(idx = 0; idx < lsdata; idx++)	// 点
                {
                    if (i >= datasize){break;}
                    ch1 = m_quiFileData.at(i++);
                    if (i >= datasize){break;}
                    ch2 = m_quiFileData.at(i++);
                    deltx = (ch2 * 256.0 + ch1);

                    if (i >= datasize){break;}
                    ch1 = m_quiFileData.at(i++);
                    if (i >= datasize){break;}
                    ch2 = m_quiFileData.at(i++);
                    delty = (ch2 * 256.0 + ch1);

                    if (first == 0)
                    {
                        m_firstPoint.x = deltx;
                        m_firstPoint.y = delty;
                        if(tmpls == QUI_TYPE_LINE)
                        {
                            m_firstPoint.ctrl = DATA_SEWING;
                        }
                        else
                        {
                            m_firstPoint.ctrl = DATA_OFFSET;
                        }
                        first = 1;
                    }

                    if(deltx > maxx)
                    {
                        maxx = deltx;
                    }
                    if(deltx < minx)
                    {
                        minx = deltx;
                    }

                    if(delty > maxy)
                    {
                        maxy = delty;
                    }
                    if(delty < miny)
                    {
                        miny = delty;
                    }
                }
                if (idx != lsdata)
                {
                    break;
                }
            }
        }
            break;
        case QUI_TYPE_ARC: // 三点圆弧
        {
            for (idx = 0; idx < 3; idx++)
            {
                // 点x
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threex[idx] = (ch2 * 256.0 + ch1);

                // 点y
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threey[idx] = (ch2 * 256.0 + ch1);

                if (first == 0)
                {
                    m_firstPoint.x = threex[0];
                    m_firstPoint.y = threey[0];
                    m_firstPoint.ctrl = DATA_SEWING;
                    first = 1;
                }
            }
            if (idx != 3)
            {
                break;
            }

            if(isThreePointOnALine(threex, threey) >= 1)	// 3点共线
            {
                //    				printf("three point on a line\n");
                if(threex[0] > maxx)	maxx = threex[0];
                if(threex[1] > maxx)	maxx = threex[1];
                if(threex[2] > maxx)	maxx = threex[2];
                if(threex[0] < minx) minx = threex[0];
                if(threex[1] < minx) minx = threex[1];
                if(threex[2] < minx)	minx = threex[2];

                if(threey[0] > maxy)	maxy = threey[0];
                if(threey[1] > maxy)	maxy = threey[1];
                if(threey[2] > maxy)	maxy = threey[2];
                if(threey[0] < miny) miny = threey[0];
                if(threey[1] < miny)	miny = threey[1];
                if(threey[2] < miny)	miny = threey[2];
            }
            else
            {
                //    				printf("before GetArcMinMax\n");
                //    				printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy);
                getArcMinMax(threex, threey, &minx, &maxx, &miny, &maxy);
                //    				printf("after GetArcMinMax\n");
                //    				printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy);
            }
        }
            break;
        case QUI_TYPE_BES: // 贝塞尔曲线
        {
            for (idx = 0; idx < 4; idx++)
            {
                // 点x
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threex[idx] = (ch2 * 256.0 + ch1);

                // 点y
                if (i >= datasize){break;}
                ch1 = m_quiFileData.at(i++);
                if (i >= datasize){break;}
                ch2 = m_quiFileData.at(i++);
                threey[idx] = (ch2 * 256.0 + ch1);

                if (first == 0)
                {
                    m_firstPoint.x = threex[0];
                    m_firstPoint.y = threey[0];
                    m_firstPoint.ctrl = DATA_SEWING;
                    first = 1;
                }
            }
            if (idx != 4)
            {
                break;
            }

            getBezierMinMax(threex, threey, &minx, &maxx, &miny, &maxy);
        }
            break;
        }
    }

    if (first == 0)
    {
        minx = 0;
        maxx = 0;
        miny = 0;
        maxy = 0;

        m_firstPoint.x = 0;
        m_firstPoint.y = 0;
        m_firstPoint.ctrl = 0;
    }

    m_minX = minx;
    m_maxX = maxx;
    m_minY = miny;
    m_maxY = maxy;

    return;
}

int DataFileQui::checkFileHead()
{
    if (m_quiFileData.size() >= (int)sizeof(QuiFileHead))
    {
        QuiFileHead * pHead;
        pHead = (QuiFileHead *)(m_quiFileData.data());

        if (pHead->normalStep < 1)
        {
            pHead->normalStep = 40;
        }

        if (pHead->miniStep < 1)
        {
            pHead->miniStep = 40;
        }

        if (pHead->scanX < 1)
        {
            pHead->scanX = m_maxX - m_minX;
        }

        if (pHead->scanY < 1)
        {
            pHead->scanY = m_maxY - m_minY;
        }

        QFile wrfile(m_fileFullPathName);
        if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            return -1;
        }
        else
        {
            wrfile.write(m_quiFileData);
            wrfile.close();
        }
    }

    return 0;
}

double DataFileQui::getMutiUnit(int unit)
{
    double unitmuti;
    if (unit == 0x00) // 0x00: 0.1mm;
    {
        unitmuti = 10;
    }
    else if (unit == 0x01) // 0x01: 1/1000inch;
    {
        unitmuti = 2.54;
    }
    else if (unit == 0x02) // 0x02: 0.04mm
    {
        unitmuti = 10;
    }
    else
    {
        unitmuti = 1;
    }
    return unitmuti;
}

void DataFileQui::initFile(const QString &fullPathName)
{
    clear();
    QFileInfo file(fullPathName);
    if (file.exists() && file.isFile())
    {
        m_fileFullPathName = fullPathName;
    }
    else
    {
        qDebug() << "Init file failed path =" << m_fileFullPathName;
    }
    loadFile();
}

void DataFileQui::clear()
{
    m_firstPoint.x = 0;
    m_firstPoint.y = 0;
    m_firstPoint.ctrl = 0;

    m_minX = INT32_MAX;
    m_maxX = INT32_MIN;
    m_minY = INT32_MAX;
    m_maxY = INT32_MIN;

    m_fileFullPathName.clear(); // 文件路径
    m_quiFileData.clear();         // 文件数据内容
    m_absData.clear();       // 转换后的数据
}

void DataFileQui::loadFile()
{
    QFile rdfile(m_fileFullPathName);
    if(!rdfile.open(QIODevice::ReadOnly))
    {
        qDebug() << "open file fail when read, path =" << m_fileFullPathName;
        return;
    }

    m_quiFileData = rdfile.readAll();
    rdfile.close();
}

int DataFileQui::createPreviewImage(QImage *pImg, int saveflag, int penwidth, int reDraw)
{
#if(1)
    s16 existFlag = 1;

    if(reDraw == 0)//图片存在则不重画
    {
        existFlag = 0;
        // 图片是否存在，存在则返回
        QString previewPath = getFileFullPathName() + ".preview.png";
        QFile imageFile(previewPath);
        if (imageFile.exists())
        {
            return 0;
        }
    }
#endif

    int newimgflag = 0;
    QImage * pImage;
    int width, height;
    if (pImg == NULL)
    {
        width = QUI_PREVIEW_WIDTH;
        height = QUI_PREVIEW_HEIGHT;
        pImage = new QImage(width, height, IMAGE_TYPE);
        newimgflag = 1;
    }
    else
    {
        pImage = pImg;
    }

    width = pImage->width();
    height = pImage->height();
    if (width <= QUI_PREVIEW_SIDE*2 || height <= QUI_PREVIEW_SIDE*2)
    {
        if (pImage != NULL && newimgflag == 1)
        {
            delete pImage;
        }
        qDebug("preview img too small");
        return -1;
    }

    memset(pImage->bits(), 0x00, pImage->byteCount());

    QPainter painter(pImage);
    QColor backcolor(255, 255, 255, 0);         // 透明背景
    // 背景
    QPen pen;
    pen.setWidth(penwidth);
    pen.setColor(backcolor);
    painter.setPen(pen);
    painter.setBrush(backcolor);
    painter.drawRect(0, 0, width, height);

    // 图形
    //qDebug()<<"convertDataToAbs defore";
    convertDataToEmbAbs(existFlag);     // 转换为绝对坐标数据
    //qDebug()<<"convertDataToAbs end";

    // absdat数据
    int size = m_absData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("2 data less then head size");
        return -1;
    }
    DataDs16FileHead * pAbsHead = (DataDs16FileHead *)(m_absData.data());
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }
    DsAbsItem * pData = (DsAbsItem *)(m_absData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;
    //--------

    // 图形显示区域
    int dpminx = QUI_PREVIEW_SIDE;
    int dpmaxx = width - QUI_PREVIEW_SIDE;
    int dpminy = QUI_PREVIEW_SIDE;
    int dpmaxy = height - QUI_PREVIEW_SIDE;

    // 计算缩放系数
    double factor, temp;
    if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0)
    {
        return -1;
    }

    factor = (double)(fabs(m_maxX - m_minX)) / (dpmaxx - dpminx);      // 按x计算的缩放系数
    temp =   (double)(fabs(m_maxY - m_minY)) / (dpmaxy - dpminy);      // 按y计算的缩放系数

    if (temp >= factor)     // 使用较大的缩放系数
    {
        factor = temp;
    }

    //计算显示参数，按照图形的实际位置显示（数据坐标零点对应图形中心）
    double dpx = (double)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2);
    double dpy = (double)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2);

    // 显示花样图形
    u8 ctrlByte;
    double dx;
    double dy;

    double datposx, datposy;
    double curx, cury, prex, prey;

    datposx = pAbsHead->beginX;
    datposy = pAbsHead->beginY;

    curx = (datposx) / factor + dpx;
    cury = (datposy) / factor + dpy;

    if (QUI_SHOWDIRX == -1)
    {
        curx = (width)-curx;
    }
    if (QUI_SHOWDIRY == -1)
    {
        cury = (height)-cury;
    }

    absDataPtr = pData;

    QColor color = QColor(Qt::green);
    pen.setColor(color);
    painter.setPen(pen);

    for (int i = 0; i < stepsize; i++)
    {
        // 读入一个针步数据
        ctrlByte = absDataPtr->ctrl;

        prex = curx;
        prey = cury;

        dx = absDataPtr->ax;
        dy = absDataPtr->ay;

        datposx = dx;
        datposy = dy;

        curx = (datposx) / factor + dpx;
        cury = (datposy) / factor + dpy;

        if (QUI_SHOWDIRX == -1)
        {
            curx = (width)-curx;
        }
        if (QUI_SHOWDIRY == -1)
        {
            cury = (height)-cury;
        }

        if(i == 0)
        {
            absDataPtr++;
            continue;
        }

        if ( ctrlByte == DATA_SEWING)
        {
            painter.drawLine(prex, prey, curx, cury);
        }
        else
        {
            //qDebug("other type=0x%x", ctrlByte);
        }

        absDataPtr++;
    }

    // 保存成文件
    QString preview = getFileFullPathName();
    if (saveflag != 0 && preview.isEmpty() == false)
    {
#if (1)
        preview += ".preview.png";
        pImage->save(preview, "png");
#endif
    }

    if (pImage != NULL && newimgflag == 1)
    {
        delete pImage;
    }

    return 0;
}

QuiFileHead *DataFileQui::getQuiHead()
{
    if(m_quiFileData.size() <= 0)
    {
        loadFile();
    }

    QuiFileHead *head = NULL;

    int size = m_quiFileData.size();
    if (size <= (int)(sizeof(QuiFileHead)))
    {
        return head;
    }

    head = (QuiFileHead *)(m_quiFileData.data());
    return head;
}

void DataFileQui::writePatternParaToFile(QuiFileHead *head)
{
    if(m_quiFileData.size() <= 0)
    {
        return;
    }

    memcpy(m_quiFileData.data(),(char*)head,sizeof(QuiFileHead));

    QFile wfile(m_fileFullPathName);
    if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "open file fail when read, path =" << m_fileFullPathName;
        return;
    }

    wfile.write(m_quiFileData);
    wfile.close();
}

void DataFileQui::moveDataBeginPonit(s32 left, s32 front)
{
    if((u32)m_absData.size() > sizeof(DataDs16FileHead))
    {
        DataDs16FileHead *dhead = (DataDs16FileHead *)( m_absData.data());
        dhead->beginX += left;
        dhead->beginY += front;
        dhead->maxX += left;
        dhead->minX += left;
        dhead->maxY += front;
        dhead->minY += front;
    }
}

int DataFileQui::getStitchNums()
{
    if(m_absData.size() <= 0)
    {
        return 0;
    }

    DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data()));
    return pHead->itemNums;
}

int DataFileQui::getDatWidth()
{
    if(m_absData.size() <= 0)
    {
        return 0;
    }

    DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data()));
    return (pHead->maxX - pHead->minX);
}

int DataFileQui::getDatHeight()
{
    if(m_absData.size() <= 0)
    {
        return 0;
    }

    DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data()));
    return (pHead->maxY - pHead->minY);
}

int DataFileQui::getMaxX()
{
    if(m_absData.size() <= 0)
    {
        return 0;
    }

    DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data()));
    return pHead->maxX;
}

int DataFileQui::getMinX()
{
    if(m_absData.size() <= 0)
    {
        return 0;
    }

    DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data()));
    return pHead->minX;
}

int DataFileQui::getMaxY()
{
    if(m_absData.size() <= 0)
    {
        return 0;
    }

    DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data()));
    return pHead->maxY;
}

int DataFileQui::getMinY()
{
    if(m_absData.size() <= 0)
    {
        return 0;
    }

    DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data()));
    return pHead->minY;
}
